From 997b8c4d6721a1cf84592d083b1b428a90c3d867 Mon Sep 17 00:00:00 2001 From: tsteven4 Date: Sat, 9 Dec 2017 08:54:26 -0700 Subject: [PATCH] modify igc writer for consistent rounding. (#146) --- igc.cc | 26 +++++++++------ reference/igc1_3d.out | 12 +++---- reference/igc1_gpx.out | 16 +++++----- reference/igc1_igc.out | 12 +++---- reference/track/skydrop~kml.igc | 56 ++++++++++++++++----------------- testo.d/igc.test | 8 ++--- 6 files changed, 69 insertions(+), 61 deletions(-) diff --git a/igc.cc b/igc.cc index eb30dbde0..9fdc16d49 100644 --- a/igc.cc +++ b/igc.cc @@ -530,15 +530,23 @@ static void get_tracks(const route_head** pres_track, const route_head** gnss_tr static char* latlon2str(const Waypoint* wpt) { static char str[18] = ""; - char lat_hemi = wpt->latitude < 0 ? 'S' : 'N'; - char lon_hemi = wpt->longitude < 0 ? 'W' : 'E'; - unsigned char lat_deg = fabs(wpt->latitude); - unsigned char lon_deg = fabs(wpt->longitude); - unsigned int lat_min = (fabs(wpt->latitude) - lat_deg) * 60000 + 0.500000000001; - unsigned int lon_min = (fabs(wpt->longitude) - lon_deg) * 60000 + 0.500000000001; - - if (snprintf(str, 18, "%02u%05u%c%03u%05u%c", - lat_deg, lat_min, lat_hemi, lon_deg, lon_min, lon_hemi) != 17) { + // We use lround here because it: + // "Returns the integral value that is nearest to x, with halfway cases rounded away from zero." + // The halfway rounding cases of *printf are not precisely defined, and can vary with implmentation. + // We don't really care which way the halfway cases go, but we want them to go that way consistenly + // across implementations. + // We also try to use a minimum of floating point arithmetic to minimize accumulated fp math errors. + long lat_milliminutes = lround(wpt->latitude * 60000.0); + long lon_milliminutes = lround(wpt->longitude * 60000.0); + char lat_hemi = lat_milliminutes < 0 ? 'S' : 'N'; + char lon_hemi = lon_milliminutes < 0 ? 'W' : 'E'; + ldiv_t lat_digits; + ldiv_t lon_digits; + lat_digits = ldiv(labs(lat_milliminutes), 60000L); + lon_digits = ldiv(labs(lon_milliminutes), 60000L); + + if (snprintf(str, 18, "%02ld%05ld%c%03ld%05ld%c", + lat_digits.quot, lat_digits.rem, lat_hemi, lon_digits.quot, lon_digits.rem, lon_hemi) != 17) { fatal(MYNAME ": Bad waypoint format '%s'\n", str); } return str; diff --git a/reference/igc1_3d.out b/reference/igc1_3d.out index 2ecdeb4e2..e50544ed0 100644 --- a/reference/igc1_3d.out +++ b/reference/igc1_3d.out @@ -2,8 +2,8 @@ AXXXZZZGPSBabel HFDTE240404 HFPLTPILOT:CHRIS JONES C010170000000000000000101 -C3040552S15036542EBORAH -C3040552S15036542EBORAH +C3040552S15036542EBORAH +C3040552S15036542EBORAH C3043796S15038952EBALDWI C3045821S15043392EMANAIR C3045821S15043392EMANAIR @@ -55,11 +55,11 @@ B0422453040722S15036423EA0096100000 B0423153040717S15036457EA0098800000 B0423453040700S15036444EA0101900000 B0424163040689S15036457EA0104100000 -B0424473040753S15036486EA0101900000 +B0424473040754S15036486EA0101900000 B0425183040750S15036329EA0099200000 B0425483040794S15036240EA0101900000 B0426193040688S15036353EA0108000000 -B0426493040679S15036400EA0111700000 +B0426493040679S15036401EA0111700000 B0427203040754S15036332EA0113300000 B0427513040693S15036316EA0113200000 B0428213040918S15036288EA0108900000 @@ -96,7 +96,7 @@ B0443383043886S15038927EA0099500000 B0444093043845S15038947EA0099400000 B0444403043904S15038862EA0099000000 B0445113043934S15038756EA0098000000 -B0445423044092S15038774EA0095300000 +B0445423044093S15038774EA0095300000 B0446133044150S15039144EA0094600000 B0446443044370S15039248EA0094100000 B0447153044594S15039415EA0092800000 @@ -105,7 +105,7 @@ B0448163044963S15040024EA0086900000 B0448473044982S15040431EA0083300000 B0449183044991S15040573EA0083000000 B0449483045154S15040808EA0081500000 -B0450193045342S15041095EA0078100000 +B0450193045342S15041096EA0078100000 B0450493045484S15041383EA0075000000 B0451193045595S15041771EA0065700000 B0451503045744S15042205EA0055400000 diff --git a/reference/igc1_gpx.out b/reference/igc1_gpx.out index f0c558820..afbb5f181 100644 --- a/reference/igc1_gpx.out +++ b/reference/igc1_gpx.out @@ -7,13 +7,13 @@ IGCDATE000000: TAKEOFF - BORAH - BORAH + BORAH + BORAH START - BORAH - BORAH + BORAH + BORAH TURN01 @@ -179,7 +179,7 @@ - + @@ -191,7 +191,7 @@ - + @@ -302,7 +302,7 @@ - + @@ -329,7 +329,7 @@ - + diff --git a/reference/igc1_igc.out b/reference/igc1_igc.out index 9d3c0071e..edfbea4ba 100644 --- a/reference/igc1_igc.out +++ b/reference/igc1_igc.out @@ -2,8 +2,8 @@ AXXXZZZGPSBabel HFDTE240404 HFPLTPILOT:CHRIS JONES C010170000000000000000101 -C3040552S15036542EBORAH -C3040552S15036542EBORAH +C3040552S15036542EBORAH +C3040552S15036542EBORAH C3043796S15038952EBALDWI C3045821S15043392EMANAIR C3045821S15043392EMANAIR @@ -55,11 +55,11 @@ B0422453040722S15036423EA0000000000 B0423153040717S15036457EA0000000000 B0423453040700S15036444EA0000000000 B0424163040689S15036457EA0000000000 -B0424473040753S15036486EA0000000000 +B0424473040754S15036486EA0000000000 B0425183040750S15036329EA0000000000 B0425483040794S15036240EA0000000000 B0426193040688S15036353EA0000000000 -B0426493040679S15036400EA0000000000 +B0426493040679S15036401EA0000000000 B0427203040754S15036332EA0000000000 B0427513040693S15036316EA0000000000 B0428213040918S15036288EA0000000000 @@ -96,7 +96,7 @@ B0443383043886S15038927EA0000000000 B0444093043845S15038947EA0000000000 B0444403043904S15038862EA0000000000 B0445113043934S15038756EA0000000000 -B0445423044092S15038774EA0000000000 +B0445423044093S15038774EA0000000000 B0446133044150S15039144EA0000000000 B0446443044370S15039248EA0000000000 B0447153044594S15039415EA0000000000 @@ -105,7 +105,7 @@ B0448163044963S15040024EA0000000000 B0448473044982S15040431EA0000000000 B0449183044991S15040573EA0000000000 B0449483045154S15040808EA0000000000 -B0450193045342S15041095EA0000000000 +B0450193045342S15041096EA0000000000 B0450493045484S15041383EA0000000000 B0451193045595S15041771EA0000000000 B0451503045744S15042205EA0000000000 diff --git a/reference/track/skydrop~kml.igc b/reference/track/skydrop~kml.igc index ce3f057eb..bdb8202b3 100644 --- a/reference/track/skydrop~kml.igc +++ b/reference/track/skydrop~kml.igc @@ -27,7 +27,7 @@ B1700274816053N00831019EA0000000792 B1700284816058N00831019EA0000000794 B1700294816063N00831019EA0000000792 B1700304816068N00831020EA0000000792 -B1700314816072N00831022EA0000000794 +B1700314816073N00831022EA0000000794 B1700324816078N00831023EA0000000797 B1700334816083N00831025EA0000000799 B1700344816087N00831027EA0000000800 @@ -52,12 +52,12 @@ B1700524816150N00831114EA0000000825 B1700534816153N00831119EA0000000827 B1700544816156N00831125EA0000000829 B1700554816159N00831131EA0000000831 -B1700564816162N00831136EA0000000833 -B1700574816165N00831142EA0000000833 +B1700564816163N00831136EA0000000833 +B1700574816166N00831142EA0000000833 B1700584816168N00831148EA0000000834 B1700594816171N00831153EA0000000836 B1701004816175N00831158EA0000000838 -B1701014816177N00831164EA0000000839 +B1701014816178N00831164EA0000000839 B1701024816181N00831169EA0000000840 B1701034816184N00831175EA0000000842 B1701044816187N00831180EA0000000843 @@ -130,7 +130,7 @@ B1702114816328N00831602EA0000000901 B1702124816329N00831610EA0000000902 B1702134816329N00831618EA0000000903 B1702144816330N00831626EA0000000903 -B1702154816330N00831633EA0000000903 +B1702154816330N00831634EA0000000903 B1702164816330N00831642EA0000000904 B1702174816330N00831650EA0000000904 B1702184816331N00831658EA0000000905 @@ -143,7 +143,7 @@ B1702244816333N00831705EA0000000904 B1702254816333N00831721EA0000000906 B1702264816333N00831729EA0000000906 B1702274816333N00831737EA0000000905 -B1702284816333N00831745EA0000000904 +B1702284816334N00831745EA0000000904 B1702294816334N00831753EA0000000904 B1702304816335N00831761EA0000000904 B1702314816335N00831770EA0000000905 @@ -169,10 +169,10 @@ B1702514816335N00831917EA0000000902 B1702524816334N00831925EA0000000903 B1702534816334N00831933EA0000000905 B1702544816333N00831941EA0000000906 -B1702554816333N00831948EA0000000906 +B1702554816333N00831949EA0000000906 B1702564816332N00831956EA0000000905 B1702574816331N00831964EA0000000904 -B1702584816330N00831972EA0000000904 +B1702584816331N00831972EA0000000904 B1702594816330N00831980EA0000000904 B1703004816329N00831988EA0000000905 B1703014816328N00831996EA0000000906 @@ -260,7 +260,7 @@ B1704234816428N00832640EA0000000921 B1704244816430N00832648EA0000000921 B1704254816432N00832656EA0000000920 B1704264816433N00832663EA0000000917 -B1704274816435N00832671EA0000000914 +B1704274816436N00832671EA0000000914 B1704284816437N00832677EA0000000911 B1704294816440N00832684EA0000000911 B1704304816443N00832691EA0000000912 @@ -439,7 +439,7 @@ B1707244816943N00833214EA0000001000 B1707254816946N00833206EA0000000999 B1707264816949N00833198EA0000000999 B1707274816951N00833190EA0000000999 -B1707284816954N00833181EA0000000998 +B1707284816954N00833182EA0000000998 B1707294816956N00833174EA0000000998 B1707304816959N00833165EA0000000998 B1707314816961N00833157EA0000000999 @@ -447,7 +447,7 @@ B1707324816964N00833148EA0000000999 B1707334816967N00833139EA0000001000 B1707344816970N00833131EA0000001000 B1707354816972N00833123EA0000000999 -B1707364816975N00833116EA0000000999 +B1707364816976N00833116EA0000000999 B1707374816979N00833108EA0000001000 B1707384816982N00833100EA0000001000 B1707394816986N00833092EA0000001001 @@ -490,7 +490,7 @@ B1708164817106N00832809EA0000001020 B1708174817108N00832801EA0000001021 B1708184817111N00832793EA0000001022 B1708194817114N00832785EA0000001022 -B1708204817116N00832777EA0000001022 +B1708204817117N00832777EA0000001022 B1708214817119N00832768EA0000001022 B1708224817122N00832760EA0000001022 B1708234817124N00832751EA0000001022 @@ -574,7 +574,7 @@ B1709414817190N00832086EA0000001053 B1709424817188N00832077EA0000001053 B1709434817185N00832067EA0000001053 B1709444817182N00832058EA0000001052 -B1709454817179N00832049EA0000001052 +B1709454817180N00832049EA0000001052 B1709464817177N00832040EA0000001050 B1709474817174N00832031EA0000001050 B1709484817171N00832022EA0000001050 @@ -600,7 +600,7 @@ B1710074817131N00831832EA0000001052 B1710084817130N00831823EA0000001051 B1710094817128N00831813EA0000001050 B1710104817127N00831803EA0000001049 -B1710114817125N00831793EA0000001050 +B1710114817126N00831793EA0000001050 B1710124817124N00831783EA0000001050 B1710134817123N00831773EA0000001050 B1710144817122N00831763EA0000001049 @@ -617,7 +617,7 @@ B1710244817110N00831665EA0000001045 B1710254817109N00831655EA0000001045 B1710264817107N00831646EA0000001045 B1710274817106N00831636EA0000001045 -B1710294817104N00831626EA0000001044 +B1710294817105N00831626EA0000001044 B1710304817103N00831616EA0000001044 B1710314817102N00831607EA0000001044 B1710324817101N00831597EA0000001044 @@ -649,7 +649,7 @@ B1710574817055N00831351EA0000001043 B1710584817053N00831342EA0000001044 B1710594817050N00831333EA0000001044 B1711004817047N00831324EA0000001046 -B1711014817045N00831315EA0000001047 +B1711014817045N00831316EA0000001047 B1711024817043N00831307EA0000001047 B1711034817040N00831298EA0000001048 B1711044817038N00831290EA0000001048 @@ -664,7 +664,7 @@ B1711124817021N00831222EA0000001057 B1711134817019N00831213EA0000001058 B1711144817018N00831204EA0000001059 B1711154817016N00831195EA0000001060 -B1711164817014N00831186EA0000001061 +B1711164817015N00831186EA0000001061 B1711174817013N00831177EA0000001061 B1711184817011N00831168EA0000001062 B1711194817009N00831159EA0000001062 @@ -687,7 +687,7 @@ B1711354816973N00831015EA0000001073 B1711364816971N00831006EA0000001073 B1711374816968N00830997EA0000001074 B1711384816966N00830988EA0000001074 -B1711394816963N00830979EA0000001074 +B1711394816964N00830979EA0000001074 B1711404816961N00830969EA0000001074 B1711414816958N00830960EA0000001075 B1711424816956N00830951EA0000001076 @@ -816,7 +816,7 @@ B1713464816682N00829864EA0000001072 B1713474816681N00829855EA0000001071 B1713484816680N00829846EA0000001069 B1713494816679N00829838EA0000001067 -B1713504816678N00829829EA0000001066 +B1713504816679N00829829EA0000001066 B1713514816677N00829821EA0000001066 B1713524816676N00829811EA0000001065 B1713534816675N00829802EA0000001064 @@ -908,7 +908,7 @@ B1715194816590N00829603EA0000001008 B1715204816585N00829609EA0000001006 B1715214816581N00829615EA0000001006 B1715224816577N00829620EA0000001005 -B1715234816573N00829626EA0000001004 +B1715234816574N00829626EA0000001004 B1715244816570N00829630EA0000001001 B1715254816565N00829636EA0000000999 B1715264816561N00829642EA0000000999 @@ -931,7 +931,7 @@ B1715434816501N00829746EA0000000986 B1715444816498N00829753EA0000000986 B1715454816494N00829759EA0000000985 B1715464816491N00829765EA0000000983 -B1715474816486N00829770EA0000000982 +B1715474816487N00829770EA0000000982 B1715484816482N00829776EA0000000982 B1715494816473N00829786EA0000000982 B1715504816469N00829792EA0000000981 @@ -1012,7 +1012,7 @@ B1717054816201N00830276EA0000000897 B1717064816198N00830284EA0000000895 B1717074816195N00830291EA0000000893 B1717084816192N00830297EA0000000891 -B1717094816189N00830304EA0000000890 +B1717094816190N00830305EA0000000890 B1717104816187N00830311EA0000000889 B1717114816183N00830319EA0000000887 B1717124816180N00830326EA0000000885 @@ -1052,7 +1052,7 @@ B1717454816101N00830561EA0000000830 B1717464816098N00830567EA0000000828 B1717474816096N00830574EA0000000826 B1717484816093N00830581EA0000000825 -B1717494816090N00830588EA0000000824 +B1717494816091N00830588EA0000000824 B1717504816088N00830595EA0000000823 B1717514816086N00830601EA0000000821 B1717524816084N00830608EA0000000819 @@ -1126,9 +1126,9 @@ B1719004816070N00830899EA0000000831 B1719014816071N00830890EA0000000832 B1719024816072N00830881EA0000000834 B1719034816074N00830873EA0000000834 -B1719044816075N00830865EA0000000833 +B1719044816076N00830865EA0000000833 B1719054816077N00830856EA0000000833 -B1719064816079N00830847EA0000000833 +B1719064816079N00830848EA0000000833 B1719074816080N00830838EA0000000834 B1719084816082N00830829EA0000000834 B1719094816083N00830820EA0000000834 @@ -1164,7 +1164,7 @@ B1719394816154N00830578EA0000000843 B1719404816158N00830570EA0000000844 B1719414816161N00830563EA0000000846 B1719424816165N00830556EA0000000846 -B1719434816168N00830550EA0000000846 +B1719434816169N00830550EA0000000846 B1719444816172N00830543EA0000000846 B1719454816175N00830537EA0000000847 B1719464816179N00830531EA0000000849 @@ -1212,7 +1212,7 @@ B1720274816149N00830412EA0000000839 B1720284816146N00830419EA0000000837 B1720294816144N00830426EA0000000836 B1720304816141N00830433EA0000000834 -B1720314816138N00830440EA0000000832 +B1720314816139N00830440EA0000000832 B1720324816136N00830448EA0000000832 B1720334816131N00830463EA0000000830 B1720344816128N00830470EA0000000828 @@ -1230,7 +1230,7 @@ B1720454816100N00830543EA0000000812 B1720464816098N00830550EA0000000811 B1720474816096N00830556EA0000000809 B1720484816093N00830563EA0000000808 -B1720494816090N00830570EA0000000806 +B1720494816091N00830570EA0000000806 B1720504816088N00830576EA0000000804 B1720524816086N00830583EA0000000802 B1720534816084N00830590EA0000000802 diff --git a/testo.d/igc.test b/testo.d/igc.test index e5e92ee34..68a1f01ee 100644 --- a/testo.d/igc.test +++ b/testo.d/igc.test @@ -10,12 +10,12 @@ gpsbabel -i igc -f ${TMPDIR}/igc.out -o gpx -F ${TMPDIR}/igc.gpx compare ${REFERENCE}/igc1_gpx.out ${TMPDIR}/igc.gpx gpsbabel -i gpx -f ${TMPDIR}/igc.gpx -o igc -F ${TMPDIR}/igc.out -sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed.out -compare ${REFERENCE}/igc1_igc.out ${TMPDIR}/igc_sed.out +sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed2.out +compare ${REFERENCE}/igc1_igc.out ${TMPDIR}/igc_sed2.out gpsbabel -i gpx -f ${REFERENCE}/igc1_baro.gpx -i igc -f ${REFERENCE}/igc1_igc.out -o igc,timeadj=auto -F ${TMPDIR}/igc.out -sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed.out -compare ${REFERENCE}/igc1_3d.out ${TMPDIR}/igc_sed.out +sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed3.out +compare ${REFERENCE}/igc1_3d.out ${TMPDIR}/igc_sed3.out gpsbabel -i igc -f ${REFERENCE}/igc2.igc -o gpx -F ${TMPDIR}/igc2~igc.gpx -- 2.30.2